package gitlab_hook

import (
	"encoding/json"
	"strings"
	"time"

	"atomgit.com/openlinksaas-org/proto-gen-go.git/events/events_gitlab"
)

type customTime struct {
	value *string
}

func (t *customTime) UnmarshalJSON(b []byte) (err error) {
	s := strings.Trim(string(b), "\"")
	if s != "null" {
		t.value = &s
	}
	return
}

func (t customTime) GetTimeStamp() []int64 {
	if t.value != nil {
		ts, err := time.Parse("2006-01-02 15:04:05 Z0700", *t.value)
		if err == nil {
			return []int64{ts.UnixNano() / 1e6}
		}
		ts, err = time.Parse(time.RFC3339, *t.value)
		if err == nil {
			return []int64{ts.UnixNano() / 1e6}
		}
	}
	return []int64{}
}

func (t customTime) MarshalJSON() ([]byte, error) {
	ts := t.GetTimeStamp()
	return json.Marshal(ts)
}

type Author struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

func (item *Author) ToProtoBuf() *events_gitlab.Author {
	return &events_gitlab.Author{
		Name:  item.Name,
		Email: item.Email,
	}
}

type Variable struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

func (item *Variable) ToProtoBuf() *events_gitlab.Variable {
	return &events_gitlab.Variable{
		Key:   item.Key,
		Value: item.Value,
	}
}

type User struct {
	Id        int64  `json:"id"`
	Name      string `json:"name"`
	UserName  string `json:"username"`
	AvatarUrl string `json:"avatar_url"`
	Email     string `json:"email"`
}

func (item *User) ToProtoBuf() *events_gitlab.User {
	return &events_gitlab.User{
		Id:        item.Id,
		Name:      item.Name,
		UserName:  item.UserName,
		AvatarUrl: item.AvatarUrl,
		Email:     item.Email,
	}
}

type BuildCommit struct {
	Id          int64      `json:"id"`
	Sha         string     `json:"sha"`
	Message     string     `json:"message"`
	AuthorName  string     `json:"author_name"`
	AuthorEmail string     `json:"author_email"`
	Status      string     `json:"status"`
	Duration    float64    `json:"duration"`
	StartedAt   customTime `json:"started_at"`
	FinishedAt  customTime `json:"finished_at"`
}

func (item *BuildCommit) ToProtoBuf() *events_gitlab.BuildCommit {
	return &events_gitlab.BuildCommit{
		Id:          item.Id,
		Sha:         item.Sha,
		Message:     item.Message,
		AuthorName:  item.AuthorName,
		AuthorEmail: item.AuthorEmail,
		Status:      item.Status,
		Duration:    float32(item.Duration),
		StartedAt:   item.StartedAt.GetTimeStamp(),
		FinishedAt:  item.FinishedAt.GetTimeStamp(),
	}
}

type Repository struct {
	Name            string `json:"name"`
	Url             string `json:"url"`
	Description     string `json:"description"`
	Homepage        string `json:"homepage"`
	GitSshUrl       string `json:"git_ssh_url"`
	GitHttpUrl      string `json:"git_http_url"`
	VisibilityLevel int64  `json:"visibility_level"`
}

func (item *Repository) ToProtoBuf() *events_gitlab.Repository {
	return &events_gitlab.Repository{
		Name:            item.Name,
		Url:             item.Url,
		Description:     item.Description,
		Homepage:        item.Homepage,
		GitSshUrl:       item.GitSshUrl,
		GitHttpUrl:      item.GitHttpUrl,
		VisibilityLevel: item.VisibilityLevel,
	}
}

type Runner struct {
	Id          int64  `json:"id"`
	Description string `json:"description"`
	Active      bool   `json:"active"`
	IsShared    bool   `json:"is_shared"`
}

func (item *Runner) ToProtoBuf() *events_gitlab.Runner {
	return &events_gitlab.Runner{
		Id:          item.Id,
		Description: item.Description,
		Active:      item.Active,
		IsShared:    item.IsShared,
	}
}

type Project struct {
	Id                int64  `json:"id"`
	Name              string `json:"name"`
	Description       string `json:"description"`
	WebUrl            string `json:"web_url"`
	AvatarUrl         string `json:"avatar_url"`
	GitSshUrl         string `json:"git_ssh_url"`
	GitHttpUrl        string `json:"git_http_url"`
	Namespace         string `json:"namespace"`
	VisibilityLevel   int64  `json:"visibility_level"`
	PathWithNamespace string `json:"path_with_namespace"`
	DefaultBranch     string `json:"default_branch"`
	Homepage          string `json:"homepage"`
	Url               string `json:"url"`
	SshUrl            string `json:"ssh_url"`
	HttpUrl           string `json:"http_url"`
}

func (item *Project) ToProtoBuf() *events_gitlab.Project {
	return &events_gitlab.Project{
		Id:                item.Id,
		Name:              item.Name,
		Description:       item.Description,
		WebUrl:            item.WebUrl,
		AvatarUrl:         item.AvatarUrl,
		GitSshUrl:         item.GitSshUrl,
		GitHttpUrl:        item.GitHttpUrl,
		Namespace:         item.Namespace,
		VisibilityLevel:   item.VisibilityLevel,
		PathWithNamespace: item.PathWithNamespace,
		DefaultBranch:     item.DefaultBranch,
		Homepage:          item.Homepage,
		Url:               item.Url,
		SshUrl:            item.SshUrl,
		HttpUrl:           item.HttpUrl,
	}
}

type Position struct {
	BaseSha      string `json:"base_sha"`
	StartSha     string `json:"start_sha"`
	HeadSha      string `json:"head_sha"`
	OldPath      string `json:"old_path"`
	NewPath      string `json:"new_path"`
	PositionType string `json:"position_type"`
	OldLine      int64  `json:"old_line"`
	NewLine      int64  `json:"new_line"`
	Width        int64  `json:"width"`
	Height       int64  `json:"height"`
	X            int64  `json:"x"`
	Y            int64  `json:"y"`
}

func (item *Position) ToProtoBuf() *events_gitlab.Position {
	return &events_gitlab.Position{
		BaseSha:      item.BaseSha,
		StartSha:     item.StartSha,
		HeadSha:      item.HeadSha,
		OldPath:      item.OldPath,
		NewPath:      item.NewPath,
		PositionType: item.PositionType,
		OldLine:      item.OldLine,
		NewLine:      item.NewLine,
		Width:        item.Width,
		Height:       item.Height,
		X:            item.X,
		Y:            item.Y,
	}
}

type StDiff struct {
	Diff        string `json:"diff"`
	NewPath     string `json:"new_path"`
	OldPath     string `json:"old_path"`
	AMode       string `json:"a_mode"`
	BMode       string `json:"b_mode"`
	NewFile     bool   `json:"new_file"`
	RenamedFile bool   `json:"renamed_file"`
	DeletedFile bool   `json:"deleted_file"`
}

func (item *StDiff) ToProtoBuf() *events_gitlab.StDiff {
	return &events_gitlab.StDiff{
		Diff:        item.Diff,
		NewPath:     item.NewPath,
		OldPath:     item.OldPath,
		AMode:       item.AMode,
		BMode:       item.BMode,
		NewFile:     item.NewFile,
		RenamedFile: item.RenamedFile,
		DeletedFile: item.DeletedFile,
	}
}

type Source struct {
	Name              string `json:"name"`
	Description       string `json:"description"`
	WebUrl            string `json:"web_url"`
	AvatarUrl         string `json:"avatar_url"`
	GitSshUrl         string `json:"git_ssh_url"`
	GitHttpUrl        string `json:"git_http_url"`
	Namespace         string `json:"namespace"`
	VisibilityLevel   int64  `json:"visibility_level"`
	PathWithNamespace string `json:"path_with_namespace"`
	DefaultBranch     string `json:"default_branch"`
	Homepage          string `json:"homepage"`
	Url               string `json:"url"`
	SshUrl            string `json:"ssh_url"`
	HttpUrl           string `json:"http_url"`
}

func (item *Source) ToProtoBuf() *events_gitlab.Source {
	return &events_gitlab.Source{
		Name:              item.Name,
		Description:       item.Description,
		WebUrl:            item.WebUrl,
		AvatarUrl:         item.AvatarUrl,
		GitSshUrl:         item.GitSshUrl,
		GitHttpUrl:        item.GitHttpUrl,
		Namespace:         item.Namespace,
		VisibilityLevel:   item.VisibilityLevel,
		PathWithNamespace: item.PathWithNamespace,
		DefaultBranch:     item.DefaultBranch,
		Homepage:          item.Homepage,
		Url:               item.Url,
		SshUrl:            item.SshUrl,
		HttpUrl:           item.HttpUrl,
	}
}

type Target struct {
	Name              string `json:"name"`
	Description       string `json:"description"`
	WebUrl            string `json:"web_url"`
	AvatarUrl         string `json:"avatar_url"`
	GitSshUrl         string `json:"git_ssh_url"`
	GitHttpUrl        string `json:"git_http_url"`
	Namespace         string `json:"namespace"`
	VisibilityLevel   int64  `json:"visibility_level"`
	PathWithNamespace string `json:"path_with_namespace"`
	DefaultBranch     string `json:"default_branch"`
	Homepage          string `json:"homepage"`
	Url               string `json:"url"`
	SshUrl            string `json:"ssh_url"`
	HttpUrl           string `json:"http_url"`
}

func (item *Target) ToProtoBuf() *events_gitlab.Target {
	return &events_gitlab.Target{
		Name:              item.Name,
		Description:       item.Description,
		WebUrl:            item.WebUrl,
		AvatarUrl:         item.AvatarUrl,
		GitSshUrl:         item.GitSshUrl,
		GitHttpUrl:        item.GitHttpUrl,
		Namespace:         item.Namespace,
		VisibilityLevel:   item.VisibilityLevel,
		PathWithNamespace: item.PathWithNamespace,
		DefaultBranch:     item.DefaultBranch,
		Homepage:          item.Homepage,
		Url:               item.Url,
		SshUrl:            item.SshUrl,
		HttpUrl:           item.HttpUrl,
	}
}

type LastCommit struct {
	Id        string     `json:"id"`
	Message   string     `json:"message"`
	Timestamp customTime `json:"timestamp"`
	Url       string     `json:"url"`
	Author    Author     `json:"author"`
}

func (item *LastCommit) ToProtoBuf() *events_gitlab.LastCommit {
	return &events_gitlab.LastCommit{
		Id:        item.Id,
		Message:   item.Message,
		Timestamp: item.Timestamp.GetTimeStamp(),
		Url:       item.Url,
		Author:    item.Author.ToProtoBuf(),
	}
}

type ObjectAttributes struct {
	Id               int64      `json:"id"`
	Title            string     `json:"title"`
	AssigneeIds      []int64    `json:"assignee_ids"`
	AssigneeId       int64      `json:"assignee_id"`
	AuthorId         int64      `json:"author_id"`
	ProjectId        int64      `json:"project_id"`
	CreatedAt        customTime `json:"created_at"`
	UpdatedAt        customTime `json:"updated_at"`
	UpdatedById      int64      `json:"updated_by_id"`
	LastEditedAt     customTime `json:"last_edited_at"`
	LastEditedById   int64      `json:"last_edited_by_id"`
	RelativePosition int64      `json:"relative_position"`
	Position         Position   `json:"position"`
	BranchName       string     `json:"branch_name"`
	Description      string     `json:"description"`
	MilestoneId      int64      `json:"milestone_id"`
	State            string     `json:"state"`
	StateId          int64      `json:"state_id"`
	ConfIdential     bool       `json:"confidential"`
	DiscussionLocked bool       `json:"discussion_locked"`
	DueDate          customTime `json:"due_date"`
	TimeEstimate     int64      `json:"time_estimate"`
	TotalTimeSpent   int64      `json:"total_time_spent"`
	Iid              int64      `json:"iid"`
	Url              string     `json:"url"`
	Action           string     `json:"action"`
	TargetBranch     string     `json:"target_branch"`
	SourceBranch     string     `json:"source_branch"`
	SourceProjectId  int64      `json:"source_project_id"`
	TargetProjectId  int64      `json:"target_project_id"`
	StCommits        string     `json:"st_commits"`
	MergeStatus      string     `json:"merge_status"`
	Content          string     `json:"content"`
	Format           string     `json:"format"`
	Message          string     `json:"message"`
	Slug             string     `json:"slug"`
	Ref              string     `json:"ref"`
	Tag              bool       `json:"tag"`
	Sha              string     `json:"sha"`
	BeforeSha        string     `json:"before_sha"`
	Status           string     `json:"status"`
	Stages           []string   `json:"stages"`
	Duration         int64      `json:"duration"`
	Note             string     `json:"note"`
	NotebookType     string     `json:"noteable_type"` // nolint:misspell
	At               customTime `json:"attachment"`
	LineCode         string     `json:"line_code"`
	CommitId         string     `json:"commit_id"`
	NoteableId       int64      `json:"noteable_id"` // nolint: misspell
	System           bool       `json:"system"`
	WorkInProgress   bool       `json:"work_in_progress"`
	StDiffs          []StDiff   `json:"st_diffs"`
	Source           Source     `json:"source"`
	Target           Target     `json:"target"`
	LastCommit       LastCommit `json:"last_commit"`
	Assignee         Assignee   `json:"assignee"`
}

func (item *ObjectAttributes) ToProtoBuf() *events_gitlab.ObjectAttributes {
	ret := &events_gitlab.ObjectAttributes{
		Id:               item.Id,
		Title:            item.Title,
		AssigneeIds:      []int64{},
		AssigneeId:       item.AssigneeId,
		AuthorId:         item.AuthorId,
		ProjectId:        item.ProjectId,
		CreatedAt:        item.CreatedAt.GetTimeStamp(),
		UpdatedAt:        item.UpdatedAt.GetTimeStamp(),
		UpdatedById:      item.UpdatedById,
		LastEditedAt:     item.LastEditedAt.GetTimeStamp(),
		LastEditedById:   item.LastEditedById,
		RelativePosition: item.RelativePosition,
		Position:         item.Position.ToProtoBuf(),
		BranchName:       item.BranchName,
		Description:      item.Description,
		MilestoneId:      item.MilestoneId,
		State:            item.State,
		StateId:          item.StateId,
		ConfIdential:     item.ConfIdential,
		DiscussionLocked: item.DiscussionLocked,
		DueDate:          item.DueDate.GetTimeStamp(),
		TimeEstimate:     item.TimeEstimate,
		TotalTimeSpent:   item.TotalTimeSpent,
		Iid:              item.Iid,
		Url:              item.Url,
		Action:           item.Action,
		TargetBranch:     item.TargetBranch,
		SourceBranch:     item.SourceBranch,
		SourceProjectId:  item.SourceProjectId,
		TargetProjectId:  item.TargetProjectId,
		StCommits:        item.StCommits,
		MergeStatus:      item.MergeStatus,
		Content:          item.Content,
		Format:           item.Format,
		Message:          item.Message,
		Slug:             item.Slug,
		Ref:              item.Ref,
		Tag:              item.Tag,
		Sha:              item.Sha,
		BeforeSha:        item.BeforeSha,
		Status:           item.Status,
		Stages:           []string{},
		Duration:         item.Duration,
		Note:             item.Note,
		NotebookType:     item.NotebookType,
		At:               item.At.GetTimeStamp(),
		LineCode:         item.LineCode,
		CommitId:         item.CommitId,
		NoteableId:       item.NoteableId,
		System:           item.System,
		WorkInProgress:   item.WorkInProgress,
		StDiffs:          []*events_gitlab.StDiff{},
		Source:           item.Source.ToProtoBuf(),
		Target:           item.Target.ToProtoBuf(),
		LastCommit:       item.LastCommit.ToProtoBuf(),
		Assignee:         item.Assignee.ToProtoBuf(),
	}
	if item.AssigneeIds != nil {
		ret.AssigneeIds = append(ret.AssigneeIds, item.AssigneeIds...)
	}
	if item.Stages != nil {
		ret.Stages = append(ret.Stages, item.Stages...)
	}
	if item.StDiffs != nil {
		for _, stdDiff := range item.StDiffs {
			ret.StDiffs = append(ret.StDiffs, stdDiff.ToProtoBuf())
		}
	}
	return ret
}

type MergeRequest struct {
	Id              int64      `json:"id"`
	TargetBranch    string     `json:"target_branch"`
	SourceBranch    string     `json:"source_branch"`
	SourceProjectId int64      `json:"source_project_id"`
	AssigneeId      int64      `json:"assignee_id"`
	AuthorId        int64      `json:"author_id"`
	Title           string     `json:"title"`
	CreatedAt       customTime `json:"created_at"`
	UpdatedAt       customTime `json:"updated_at"`
	MilestoneId     int64      `json:"milestone_id"`
	State           string     `json:"state"`
	MergeStatus     string     `json:"merge_status"`
	TargetProjectId int64      `json:"target_project_id"`
	Iid             int64      `json:"iid"`
	Description     string     `json:"description"`
	Position        int64      `json:"position"`
	LockedAt        customTime `json:"locked_at"`
	Source          Source     `json:"source"`
	Target          Target     `json:"target"`
	LastCommit      LastCommit `json:"last_commit"`
	WorkInProgress  bool       `json:"work_in_progress"`
	Assignee        Assignee   `json:"assignee"`
	Url             string     `json:"url"`
}

func (item *MergeRequest) ToProtoBuf() *events_gitlab.MergeRequest {
	return &events_gitlab.MergeRequest{
		Id:              item.Id,
		TargetBranch:    item.TargetBranch,
		SourceBranch:    item.SourceBranch,
		SourceProjectId: item.SourceProjectId,
		AssigneeId:      item.AssigneeId,
		AuthorId:        item.AuthorId,
		Title:           item.Title,
		CreatedAt:       item.CreatedAt.GetTimeStamp(),
		UpdatedAt:       item.UpdatedAt.GetTimeStamp(),
		MilestoneId:     item.MilestoneId,
		State:           item.State,
		MergeStatus:     item.MergeStatus,
		TargetProjectId: item.TargetProjectId,
		Iid:             item.Iid,
		Description:     item.Description,
		Position:        item.Position,
		LockedAt:        item.LockedAt.GetTimeStamp(),
		Source:          item.Source.ToProtoBuf(),
		Target:          item.Target.ToProtoBuf(),
		LastCommit:      item.LastCommit.ToProtoBuf(),
		WorkInProgress:  item.WorkInProgress,
		Assignee:        item.Assignee.ToProtoBuf(),
		Url:             item.Url,
	}
}

type Commit struct {
	Id        string     `json:"id"`
	Message   string     `json:"message"`
	Title     string     `json:"title"`
	Timestamp customTime `json:"timestamp"`
	Url       string     `json:"url"`
	Author    Author     `json:"author"`
	Added     []string   `json:"added"`
	Modified  []string   `json:"modified"`
	Removed   []string   `json:"removed"`
}

func (item *Commit) ToProtoBuf() *events_gitlab.Commit {
	ret := &events_gitlab.Commit{
		Id:        item.Id,
		Message:   item.Message,
		Title:     item.Title,
		Timestamp: item.Timestamp.GetTimeStamp(),
		Url:       item.Url,
		Author:    item.Author.ToProtoBuf(),
		Added:     []string{},
		Modified:  []string{},
		Removed:   []string{},
	}
	if item.Added != nil {
		ret.Added = append(ret.Added, item.Added...)
	}
	if item.Modified != nil {
		ret.Modified = append(ret.Modified, item.Modified...)
	}
	if item.Removed != nil {
		ret.Removed = append(ret.Removed, item.Removed...)
	}
	return ret
}

type Issue struct {
	Id          int64      `json:"id"`
	Title       string     `json:"title"`
	AssigneeId  int64      `json:"assignee_id"`
	AuthorId    int64      `json:"author_id"`
	ProjectId   int64      `json:"project_id"`
	CreatedAt   customTime `json:"created_at"`
	UpdatedAt   customTime `json:"updated_at"`
	Position    int64      `json:"position"`
	BranchName  string     `json:"branch_name"`
	Description string     `json:"description"`
	MilestoneId int64      `json:"milestone_id"`
	State       string     `json:"state"`
	Iid         int64      `json:"iid"`
}

func (item *Issue) ToProtoBuf() *events_gitlab.Issue {
	return &events_gitlab.Issue{
		Id:          item.Id,
		Title:       item.Title,
		AssigneeId:  item.AssigneeId,
		AuthorId:    item.AuthorId,
		ProjectId:   item.ProjectId,
		CreatedAt:   item.CreatedAt.GetTimeStamp(),
		UpdatedAt:   item.UpdatedAt.GetTimeStamp(),
		Position:    item.Position,
		BranchName:  item.BranchName,
		Description: item.Description,
		MilestoneId: item.MilestoneId,
		State:       item.State,
		Iid:         item.Iid,
	}
}

type Snippet struct {
	Id              int64      `json:"id"`
	Title           string     `json:"title"`
	Content         string     `json:"content"`
	AuthorId        int64      `json:"author_id"`
	ProjectId       int64      `json:"project_id"`
	CreatedAt       customTime `json:"created_at"`
	UpdatedAt       customTime `json:"updated_at"`
	FileName        string     `json:"file_name"`
	ExpiresAt       customTime `json:"expires_at"`
	Type            string     `json:"type"`
	VisibilityLevel int64      `json:"visibility_level"`
}

func (item *Snippet) ToProtoBuf() *events_gitlab.Snippet {
	return &events_gitlab.Snippet{
		Id:              item.Id,
		Title:           item.Title,
		Content:         item.Content,
		AuthorId:        item.AuthorId,
		ProjectId:       item.ProjectId,
		CreatedAt:       item.CreatedAt.GetTimeStamp(),
		UpdatedAt:       item.UpdatedAt.GetTimeStamp(),
		FileName:        item.FileName,
		ExpiresAt:       item.ExpiresAt.GetTimeStamp(),
		Type:            item.Type,
		VisibilityLevel: item.VisibilityLevel,
	}
}

type Assignee struct {
	Id        int64  `json:"id"`
	Name      string `json:"name"`
	Username  string `json:"username"`
	AvatarUrl string `json:"avatar_url"`
	Email     string `json:"email"`
}

func (item *Assignee) ToProtoBuf() *events_gitlab.Assignee {
	return &events_gitlab.Assignee{
		Id:        item.Id,
		Name:      item.Name,
		Username:  item.Username,
		AvatarUrl: item.AvatarUrl,
		Email:     item.Email,
	}
}

type LabelChanges struct {
	Previous []Label `json:"previous"`
	Current  []Label `json:"current"`
}

func (item *LabelChanges) ToProtoBuf() *events_gitlab.LabelChanges {
	ret := &events_gitlab.LabelChanges{
		Previous: []*events_gitlab.Label{},
		Current:  []*events_gitlab.Label{},
	}
	if item.Previous != nil {
		for _, label := range item.Previous {
			ret.Previous = append(ret.Previous, label.ToProtoBuf())
		}
	}
	if item.Current != nil {
		for _, label := range item.Current {
			ret.Current = append(ret.Current, label.ToProtoBuf())
		}
	}
	return ret
}

type Label struct {
	Id          int64      `json:"id"`
	Title       string     `json:"title"`
	Color       string     `json:"color"`
	ProjectId   int64      `json:"project_id"`
	CreatedAt   customTime `json:"created_at"`
	UpdatedAt   customTime `json:"updated_at"`
	Template    bool       `json:"template"`
	Description string     `json:"description"`
	Type        string     `json:"type"`
	GroupId     int64      `json:"group_id"`
}

func (item *Label) ToProtoBuf() *events_gitlab.Label {
	return &events_gitlab.Label{
		Id:          item.Id,
		Title:       item.Title,
		Color:       item.Color,
		ProjectId:   item.ProjectId,
		CreatedAt:   item.CreatedAt.GetTimeStamp(),
		UpdatedAt:   item.UpdatedAt.GetTimeStamp(),
		Template:    item.Template,
		Description: item.Description,
		Type:        item.Type,
		GroupId:     item.GroupId,
	}
}

type Changes struct {
	LabelChanges LabelChanges `json:"labels"`
}

func (item *Changes) ToProtoBuf() *events_gitlab.Changes {
	return &events_gitlab.Changes{
		LabelChanges: item.LabelChanges.ToProtoBuf(),
	}
}

type PipelineObjectAttributes struct {
	Id         int64      `json:"id"`
	Ref        string     `json:"ref"`
	Tag        bool       `json:"tag"`
	Sha        string     `json:"sha"`
	BeforeSha  string     `json:"before_sha"`
	Source     string     `json:"source"`
	Status     string     `json:"status"`
	Stages     []string   `json:"stages"`
	CreatedAt  customTime `json:"created_at"`
	FinishedAt customTime `json:"finished_at"`
	Duration   int64      `json:"duration"`
	Variables  []Variable `json:"variables"`
}

func (item *PipelineObjectAttributes) ToProtoBuf() *events_gitlab.PipelineObjectAttributes {
	ret := &events_gitlab.PipelineObjectAttributes{
		Id:         item.Id,
		Ref:        item.Ref,
		Tag:        item.Tag,
		Sha:        item.Sha,
		BeforeSha:  item.BeforeSha,
		Source:     item.Source,
		Status:     item.Status,
		Stages:     []string{},
		CreatedAt:  item.CreatedAt.GetTimeStamp(),
		FinishedAt: item.FinishedAt.GetTimeStamp(),
		Duration:   item.Duration,
		Variables:  []*events_gitlab.Variable{},
	}
	if item.Stages != nil {
		ret.Stages = append(ret.Stages, item.Stages...)
	}
	if item.Variables != nil {
		for _, variable := range item.Variables {
			ret.Variables = append(ret.Variables, variable.ToProtoBuf())
		}
	}
	return ret
}

type ArtifactsFile struct {
	Filename string `json:"filename"`
	Size     string `json:"size"`
}

func (item *ArtifactsFile) ToProtoBuf() *events_gitlab.ArtifactsFile {
	return &events_gitlab.ArtifactsFile{
		Filename: item.Filename,
		Size:     item.Size,
	}
}

type Build struct {
	Id            int64         `json:"id"`
	Stage         string        `json:"stage"`
	Name          string        `json:"name"`
	Status        string        `json:"status"`
	CreatedAt     customTime    `json:"created_at"`
	StartedAt     customTime    `json:"started_at"`
	FinishedAt    customTime    `json:"finished_at"`
	When          string        `json:"when"`
	Manual        bool          `json:"manual"`
	User          User          `json:"user"`
	Runner        Runner        `json:"runner"`
	ArtifactsFile ArtifactsFile `json:"artifactsfile"`
}

func (item *Build) ToProtoBuf() *events_gitlab.Build {
	return &events_gitlab.Build{
		Id:            item.Id,
		Stage:         item.Stage,
		Name:          item.Name,
		Status:        item.Status,
		CreatedAt:     item.CreatedAt.GetTimeStamp(),
		StartedAt:     item.StartedAt.GetTimeStamp(),
		FinishedAt:    item.FinishedAt.GetTimeStamp(),
		When:          item.When,
		Manual:        item.Manual,
		User:          item.User.ToProtoBuf(),
		Runner:        item.Runner.ToProtoBuf(),
		ArtifactsFile: item.ArtifactsFile.ToProtoBuf(),
	}
}

type Wiki struct {
	WebUrl            string `json:"web_url"`
	GitSshUrl         string `json:"git_ssh_url"`
	GitHttpUrl        string `json:"git_http_url"`
	PathWithNamespace string `json:"path_with_namespace"`
	DefaultBranch     string `json:"default_branch"`
}

func (item *Wiki) ToProtoBuf() *events_gitlab.Wiki {
	return &events_gitlab.Wiki{
		WebUrl:            item.WebUrl,
		GitSshUrl:         item.GitSshUrl,
		GitHttpUrl:        item.GitHttpUrl,
		PathWithNamespace: item.PathWithNamespace,
		DefaultBranch:     item.DefaultBranch,
	}
}
